package com.cap.bts.crmdp.dealer.masterinfo.dao.impl;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.engine.SessionFactoryImplementor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.cap.bts.crmdp.dealer.masterinfo.dao.IOtherProductDao;
import com.cap.bts.crmdp.dealer.masterinfo.domain.OtherProductModel;
import com.cap.bts.framework.common.dao.callback.NativeQueryJpaCallback;
import com.cap.bts.framework.common.dao.impl.BaseDaoImpl;
import com.cap.bts.framework.common.exception.AppException;

@Repository("iOtherProductDao")
public class OtherProductDaoImpl extends BaseDaoImpl<OtherProductModel, Long> implements
                                                                             IOtherProductDao {
	
//	private static Logger logger = Logger.getLogger(OtherProductDaoImpl.class);
	
    @Inject
    public OtherProductDaoImpl(@Value("com.cap.bts.crmdp.dealer.masterinfo.domain.OtherProductModel") Class<OtherProductModel> clazz) {
        super(clazz);

    }

    @Override
    public OtherProductModel insertOtherProductInfo(OtherProductModel otherProductModel)
                                                                                        throws AppException {
        return save(otherProductModel);
    }

    @Override
    public void removeOtherProduct(OtherProductModel otherProductModel) throws AppException {
        remove(otherProductModel);
    }
    @Override
    public void removeAllOtherProduct() throws AppException {
    	String sql = "delete from tm_other_product ";
    	
    	super.getEntityManager().createNativeQuery(sql).executeUpdate();
    }

    @Override
    public List<OtherProductModel> getAllTOtherProduct() throws AppException {
        String selectStr = "select * from tm_other_product a";
        // 查询结果集的SQL
        StringBuilder selectSql = new StringBuilder();

        StringBuilder where = new StringBuilder();
        where.append(" where 1=1 ");

        selectSql.append(selectStr).append(where.toString());

        return super.getJpaTemplate().execute(
            new NativeQueryJpaCallback<OtherProductModel>(selectSql.toString(),
                OtherProductModel.class));
    }

    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      2015年10月27日
     * @see com.cap.bts.crmdp.dealer.masterinfo.dao.IOtherProductDao#getViewForOtherProduct(java.lang.String)
    **/
    @Override
    public List<OtherProductModel> getViewForOtherProduct(String sql) throws AppException {
        return this.getListByNativeQuery(sql);
    }

    /**
     * 根据编号查询信息
     * @see com.cap.bts.crmdp.dealer.masterinfo.dao.IOtherProductDao#getOtherProductList(java.lang.String)
     */
    @Override
    public List<OtherProductModel> getOtherProductList(String mfgrCode) throws AppException {
        String sqlString = "select * from tm_other_product where MFGRCODE=?1";

        return super.getListByNativeQueryWithVaParam(sqlString,
            mfgrCode);
    }

    @Override
    public boolean updateOtherProductInfo(OtherProductModel otherProductModel, Long id)
                                                                                       throws AppException {
        OtherProductModel otherProductModel2 = findById(id);
        otherProductModel2.setPartType(otherProductModel.getPartType());
        otherProductModel2.setMfgrNo(otherProductModel.getMfgrNo());
        otherProductModel2.setNameCn(otherProductModel.getNameCn());
        otherProductModel2.setNameEn(otherProductModel.getNameEn());
        otherProductModel2.setBrandNameCN(otherProductModel.getBrandNameCN());
        otherProductModel2.setBrandNameEN(otherProductModel.getBrandNameEN());
        otherProductModel2.setSeriesNameCN(otherProductModel.getSeriesNameCN());
        otherProductModel2.setSeriesNameEN(otherProductModel.getSeriesNameEN());
        otherProductModel2.setVehicleType(otherProductModel.getVehicleType());
        otherProductModel2.setSizeDesc(otherProductModel.getSizeDesc());
        otherProductModel2.setSize(otherProductModel.getSize());
        otherProductModel2.setSizeType(otherProductModel.getSizeType());
        otherProductModel2.setSizeUnit(otherProductModel.getSizeUnit());
        otherProductModel2.setSalesType(otherProductModel.getSalesType());
        otherProductModel2.setPriceref(otherProductModel.getPriceref());
        otherProductModel2.setRemark(otherProductModel.getRemark());
        otherProductModel2.setDescription(otherProductModel.getDescription());
        otherProductModel2.setAttrA(otherProductModel.getAttrA());
        otherProductModel2.setAttrB(otherProductModel.getAttrB());
        otherProductModel2.setAttrC(otherProductModel.getAttrC());
        otherProductModel2.setAttrD(otherProductModel.getAttrD());
        otherProductModel2.setAttrE(otherProductModel.getAttrE());
        otherProductModel2.setAttrF(otherProductModel.getAttrF());
        otherProductModel2.setAttrG(otherProductModel.getAttrG());
        otherProductModel2.setAttrH(otherProductModel.getAttrH());
        otherProductModel2.setAttrI(otherProductModel.getAttrI());
        otherProductModel2.setAttrJ(otherProductModel.getAttrJ());
        otherProductModel2.setAttrK(otherProductModel.getAttrK());

        update(otherProductModel2);
        return true;
    }
    
    @Override
    public void batchInsert(List<OtherProductModel> productDataList) throws AppException{
    	Session session = (org.hibernate.Session) getEntityManager().getDelegate();
		SessionFactoryImplementor sf = (SessionFactoryImplementor) session.getSessionFactory();
		Connection connection = null;
		PreparedStatement pstmt = null;
		PreparedStatement pstmtDel = null;
		String batchId = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + "_" + ((int) (Math.random() * (99999 - 10000 + 1)) + 10000);
		try{
			connection = sf.getConnectionProvider().getConnection();
			connection.setAutoCommit(false);
			
			String sql ="INSERT INTO tm_other_product (  " +
					"  PARTTYPE,  " +
					"  MFGRCODE,  " +
					"  MFGRNO,  " +
					"  NAMECN,  " +
					"  NAMEEN,  " +
					"  BRANDNAMECN,  " +
					"  BRANDNAMEEN,  " +
					"  SERIESNAMECN,  " +
					"  SERIESNAMEEN,  " +
					"  VEHICLETYPE,  " +
					"  SIZEDESC,  " +
					"  SIZE,  " +
					"  SIZETYPE,  " +
					"  SIZEUNIT,  " +
					"  SALESTYPE,  " +
					"  PRICEREF,  " +
					"  REMARK,  " +
					"  DESCRIPTION,  " +
					"  ATTRA,  " +
					"  ATTRB,  " +
					"  ATTRC,  " +
					"  ATTRD,  " +
					"  ATTRE,  " +
					"  ATTRF,  " +
					"  ATTRG,  " +
					"  ATTRH,  " +
					"  ATTRI,  " +
					"  ATTRJ,  " +
					"  ATTRK,  " +
					"  CREATE_BY,  " +
					"  CREATE_DATE,  " +
					"  LAST_UPDATE_BY,  " +
					"  LAST_UPDATE_DATE,  " +
					"  BATCH_ID  " +
					" )  " +
					" VALUES  " +
					" (  " +
					"  ?,  " +
					"  ?,  " +
					"  ?,  " +
					"  ?,  " +
					"  ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ?,  " +
					" ? )";
			
			pstmt = connection.prepareStatement(sql);
			
			Timestamp time = new Timestamp(new Date().getTime());
			int i = 0;
			for (OtherProductModel dto : productDataList) {
				i++;
				
				pstmt.setString(1, dto.getPartType());
				pstmt.setString(2, dto.getMfgrCode());
				pstmt.setString(3, dto.getMfgrNo());
				pstmt.setString(4, dto.getNameCn());
				pstmt.setString(5, dto.getNameEn());
				pstmt.setString(6, dto.getBrandNameCN());
				pstmt.setString(7, dto.getBrandNameEN());
				pstmt.setString(8, dto.getSeriesNameCN());
				pstmt.setString(9, dto.getSeriesNameEN());
				pstmt.setString(10, dto.getVehicleType());
				pstmt.setString(11, dto.getSizeDesc());
				pstmt.setString(12, dto.getSize());
				pstmt.setString(13, dto.getSizeType());
				pstmt.setString(14, dto.getSizeUnit());
				pstmt.setString(15, dto.getSalesType());
				pstmt.setString(16, dto.getPriceref());
				pstmt.setString(17, dto.getRemark());
				pstmt.setString(18, dto.getDescription());
				pstmt.setString(19, dto.getAttrA());
				pstmt.setString(20, dto.getAttrB());
				pstmt.setString(21, dto.getAttrC());
				pstmt.setString(22, dto.getAttrD());
				pstmt.setString(23, dto.getAttrE());
				pstmt.setString(24, dto.getAttrF());
				pstmt.setString(25, dto.getAttrG());
				pstmt.setString(26, dto.getAttrH());
				pstmt.setString(27, dto.getAttrI());
				pstmt.setString(28, dto.getAttrJ());
				pstmt.setString(29, dto.getAttrK());
				pstmt.setInt(30, 0);
				pstmt.setTimestamp(31, time);
				pstmt.setInt(32, 0);
				pstmt.setTimestamp(33, time);
				pstmt.setString(34, batchId);
				
				pstmt.addBatch();
				
				if(i%30000 == 0){
					pstmt.executeBatch();     
					connection.commit();     
					pstmt.clearBatch(); 
				}
			}
			
			if(i%30000 != 0){
				pstmt.executeBatch();     
				connection.commit();     
			}
			
			
			String delSql = "delete from tm_other_product where BATCH_ID <> ?  or BATCH_ID is null";
			
			pstmtDel =  connection.prepareStatement(delSql);
			pstmtDel.setString(1, batchId);
			pstmtDel.executeUpdate();			
			
			String initSql = "{call prc_item_master_update()}";
			
			CallableStatement callableStatement = connection.prepareCall(initSql);
			callableStatement.executeUpdate();
			callableStatement.close();
			
			connection.commit();
			
		}catch(Exception e){
			try {
				connection.rollback();
			} catch (SQLException e1) {
				logger.error("", e1);
			}
			throw new AppException("ERROR", e);
		}finally{
			try {
				if(pstmt != null){
					pstmt.close();
				}
				if(connection != null){
					connection.setAutoCommit(true);
					if(pstmtDel != null){
						pstmtDel.close();
					}
					connection.close();
				}
			} catch (Exception e) {
				logger.error("", e);
				pstmt = null;
				pstmtDel = null;
				connection = null;
			}
		}
    	
    	
    	
    }
}
